fix(directory): expose directory_group_id filter in list_directory_users#149
fix(directory): expose directory_group_id filter in list_directory_users#149ravibits wants to merge 6 commits into
Conversation
The proto field existed (field 6 in ListDirectoryUsersRequest) but was never wired through the Python SDK wrapper. Adds the missing param and test coverage for filtering by group and listing groups. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
WalkthroughAdds an optional directory_group_id parameter to DirectoryClient.list_directory_users (documented and forwarded to the RPC), ensures list_directory_groups initializes its groups list, and adds tests validating listing, filtering by group, and group listing. ChangesDirectory client updates and tests
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
tests/test_directory.py (1)
144-162: Strengthen the group-filter test so it actually validates filtering/wiring.At Lines 157-161, asserting
len(response[0].users) == 0with a nonexistent group can pass even ifdirectory_group_idis ignored (because the directory may already have no users). Consider asserting request wiring via a unit-level mock or using fixture data where unfiltered results are non-empty and filtered results differ.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/test_directory.py` around lines 144 - 162, The test test_list_directory_users_filter_by_group currently asserts zero users for a nonexistent directory_group_id which can pass even if directory_group_id is ignored; change it to explicitly validate the filter wiring by either (a) creating fixture data: create at least one user in the directory and a separate user assigned to a real group, then call list_directory_users twice (once without directory_group_id and once with a valid directory_group_id) and assert the unfiltered response contains users while the filtered response only contains the group member(s), or (b) use a unit-level mock for scalekit_client.directory.list_directory_users to assert it was called with the directory_group_id parameter; locate the test by function name test_list_directory_users_filter_by_group and update calls to list_directory_users and the setup using CreateDirectory/CreateOrganization to ensure the scenario proves the filter is applied.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@scalekit/directory.py`:
- Around line 75-76: The parameter order change in list_directory_users broke
positional-argument compatibility: move updated_after before directory_group_id
so existing positional callers keep passing their sixth argument to
updated_after; update the function signature of list_directory_users to restore
the original parameter ordering (place updated_after ahead of
directory_group_id) and ensure any internal calls or references to these
parameter names remain working with the restored order.
---
Nitpick comments:
In `@tests/test_directory.py`:
- Around line 144-162: The test test_list_directory_users_filter_by_group
currently asserts zero users for a nonexistent directory_group_id which can pass
even if directory_group_id is ignored; change it to explicitly validate the
filter wiring by either (a) creating fixture data: create at least one user in
the directory and a separate user assigned to a real group, then call
list_directory_users twice (once without directory_group_id and once with a
valid directory_group_id) and assert the unfiltered response contains users
while the filtered response only contains the group member(s), or (b) use a
unit-level mock for scalekit_client.directory.list_directory_users to assert it
was called with the directory_group_id parameter; locate the test by function
name test_list_directory_users_filter_by_group and update calls to
list_directory_users and the setup using CreateDirectory/CreateOrganization to
ensure the scenario proves the filter is applied.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: f4d4db48-083b-46e1-9550-5580d7d08797
📒 Files selected for processing (2)
scalekit/directory.pytests/test_directory.py
…mpty users attr on ListDirUsersResponse is only set when the loop runs — accessing it on an empty response raises AttributeError. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…up filter test - Initialize users=[] and groups=[] before mapping loops in list_directory_users and list_directory_groups — slots were unset causing AttributeError on non-empty responses - Replace weak group filter test (nonexistent ID) with real SCIM-seeded test: creates a user+group via SCIM, asserts filtered result contains exactly that user Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ve positional arg order Inserting before updated_after would silently break callers passing updated_after positionally. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
🧹 Nitpick comments (3)
tests/test_directory.py (3)
159-159: 💤 Low valueDirect
os.environ[...]access yields an opaqueKeyErrorwhen unset.If
SCALEKIT_ENV_URLisn't configured, this fails with a bareKeyErrorrather than a clear skip/assertion. Consider guarding it.♻️ Optional guard
- env_url = os.environ['SCALEKIT_ENV_URL'].rstrip('/') + env_url = os.environ.get('SCALEKIT_ENV_URL') + if not env_url: + self.skipTest("SCALEKIT_ENV_URL not configured") + env_url = env_url.rstrip('/')🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/test_directory.py` at line 159, The test currently reads SCALEKIT_ENV_URL directly into env_url which raises a bare KeyError if the env var is missing; change the access in tests/test_directory.py so you first retrieve the value with os.environ.get or os.getenv('SCALEKIT_ENV_URL') and, if it's None/empty, call pytest.skip (or assert with a clear message) before using .rstrip('/'); update the env_url assignment and any subsequent use to handle the guarded case and reference SCALEKIT_ENV_URL and the env_url variable so the test fails/skips with a clear message instead of raising KeyError.
173-189: ⚡ Quick winAdd a timeout to the SCIM
requests.postcalls.Both POSTs lack a timeout, so a stalled SCIM endpoint can hang the test run indefinitely. Flagged by static analysis (S113).
♻️ Add timeouts
user_r = requests.post(f'{scim_base}/Users', json={ 'schemas': ['urn:ietf:params:scim:schemas:core:2.0:User'], 'userName': email, 'name': {'givenName': fake.first_name(), 'familyName': fake.last_name()}, 'emails': [{'value': email, 'primary': True}], 'active': True - }, headers=headers) + }, headers=headers, timeout=30)group_r = requests.post(f'{scim_base}/Groups', json={ 'schemas': ['urn:ietf:params:scim:schemas:core:2.0:Group'], 'displayName': fake.bs(), 'members': [{'value': scim_user_id}] - }, headers=headers) + }, headers=headers, timeout=30)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/test_directory.py` around lines 173 - 189, The two SCIM POST calls creating user_r and group_r currently call requests.post without a timeout; update both calls (the requests.post that assigns user_r and the requests.post that assigns group_r) to pass an explicit timeout (e.g. timeout=<reasonable_seconds> or a TEST_TIMEOUT constant) so the tests fail fast on a stalled SCIM endpoint; ensure both requests include the same timeout value and run the tests to confirm no breakage.
199-200: 🏗️ Heavy liftRemove the SCIM-id vs directory-id mismatch concern; keep an eventual-consistency/flakiness guard
list_directory_userspopulatesresponse[0].users[].idby copying the underlyingListDirectoryUsersuser.iddirectly (dir_user.id = user.id), and the protobuf documentsDirectoryUser.idas Scalekit’s “User ID” (diruser_*). Since the test uses the SCIMidboth for groupmembers[].valueand for the finalusers[0].idassertion, the identifier types are aligned with what the directory API returns.- The only remaining risk is timing: if the SCIM POSTs aren’t immediately reflected in
list_directory_users, lines 199-200 may become flaky; add polling/retry (or an explicit sync trigger) if failures occur.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/test_directory.py` around lines 199 - 200, The test's assertion comparing response[0].users[0].id to scim_user_id is valid (IDs align), but may be flaky due to eventual consistency; update the test around list_directory_users to retry/poll until the expected user appears (e.g., call list_directory_users in a short loop with sleeps and a timeout) instead of a single immediate assert, so functions/methods involved are list_directory_users and the test's scim POST flow that creates the user; keep the same final equality assertion but gate it behind the retry/poll loop to avoid transient failures.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@tests/test_directory.py`:
- Line 159: The test currently reads SCALEKIT_ENV_URL directly into env_url
which raises a bare KeyError if the env var is missing; change the access in
tests/test_directory.py so you first retrieve the value with os.environ.get or
os.getenv('SCALEKIT_ENV_URL') and, if it's None/empty, call pytest.skip (or
assert with a clear message) before using .rstrip('/'); update the env_url
assignment and any subsequent use to handle the guarded case and reference
SCALEKIT_ENV_URL and the env_url variable so the test fails/skips with a clear
message instead of raising KeyError.
- Around line 173-189: The two SCIM POST calls creating user_r and group_r
currently call requests.post without a timeout; update both calls (the
requests.post that assigns user_r and the requests.post that assigns group_r) to
pass an explicit timeout (e.g. timeout=<reasonable_seconds> or a TEST_TIMEOUT
constant) so the tests fail fast on a stalled SCIM endpoint; ensure both
requests include the same timeout value and run the tests to confirm no
breakage.
- Around line 199-200: The test's assertion comparing response[0].users[0].id to
scim_user_id is valid (IDs align), but may be flaky due to eventual consistency;
update the test around list_directory_users to retry/poll until the expected
user appears (e.g., call list_directory_users in a short loop with sleeps and a
timeout) instead of a single immediate assert, so functions/methods involved are
list_directory_users and the test's scim POST flow that creates the user; keep
the same final equality assertion but gate it behind the retry/poll loop to
avoid transient failures.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 926d0604-85aa-4c62-8703-41da6cf5a0fd
📒 Files selected for processing (2)
scalekit/directory.pytests/test_directory.py
🚧 Files skipped from review as they are similar to previous changes (1)
- scalekit/directory.py
Summary
list_directory_userswas missing thedirectory_group_idparameter despite it being defined as field 6 in theListDirectoryUsersRequestprotodirectory_group_id: Optional[str] = Noneto the method signature and wired it through to the gRPC requesttest_list_directory_users,test_list_directory_users_filter_by_group,test_list_directory_groupsTest plan
test_list_directory_users— basic call returns OK with no filtertest_list_directory_users_filter_by_group— passing a group ID is accepted, returns empty users list for nonexistent grouptest_list_directory_groups— basic group listing returns OK🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes
Tests